/**
  ******************************************************************************
  * File Name          : ltlx.c
  * Description        : 
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tskcfg.h"
#include "bsp.h"
#include "xc.h"
#include "storage.h"
#include "route_base.h"
#include <string.h>

#define XC_STORAGE_OTTM_ADDRESS      EEPROM_BLOCK01
#define XC_STORAGE_CPOS_ADDRESS      EEPROM_BLOCK02
#define XC_STORAGE_UPLT_ADDRESS      EEPROM_BLOCK03

const Xc_StorageTypeType Xc_SaveOutTime = XC_STORAGE_TYPE_OTTM;
const Xc_StorageTypeType Xc_SaveCurrentPosition = XC_STORAGE_TYPE_CPOS;
const Xc_StorageTypeType Xc_SaveUpLimit = XC_STORAGE_TYPE_UPLT;

Xc_StorageOttmType xc_storage_ottm;
Xc_StorageCPosType xc_storage_cpos;
Xc_StorageUpltType xc_storage_uplt;

const uint8_t  Xc_InitOutTime = 90;
const uint8_t  Xc_InitCurrentPosition = 50;
const uint16_t Xc_InitUpLimit = 15000;

volatile uint8_t  Xc_OutTime = Xc_InitOutTime;
volatile uint8_t  Xc_CurrentPosition = Xc_InitCurrentPosition;
volatile uint16_t Xc_UpLimit = Xc_InitUpLimit;


uint8_t Xc_CheckOutTime(uint8_t ottm)
{
  if((ottm < 90)||(ottm > 250))
  {
    return 1;
  }
  
  return 0;
}

uint8_t Xc_CheckCurrentPosition(uint8_t cpos)
{
  if(cpos > 101)
  {
    return 1;
  }
  
  return 0;
}

uint8_t Xc_CheckUpLimit(uint16_t uplt)
{
  if(uplt > 20000)
  {
    return 1;
  }
  
  return 0;
}

static void storage_save_initottm(void)
{
  memset(&xc_storage_ottm, 0, sizeof(Xc_StorageOttmType));
  
  xc_storage_ottm.ottm = Xc_InitOutTime;
  
  xc_storage_ottm.crc16 = crc16((uint8_t *)&xc_storage_ottm.ottm, sizeof(Xc_OutTime));
  
  eEPRom_Write(XC_STORAGE_OTTM_ADDRESS, (const uint8_t*)&xc_storage_ottm, sizeof(Xc_StorageOttmType));
  
  Xc_OutTime = Xc_InitOutTime;
  
  printf("Xc Init out time saved!\r\n");
}

static void storage_save_initcpos(void)
{
  memset(&xc_storage_cpos, 0, sizeof(Xc_StorageCPosType));
  
  xc_storage_cpos.cpos = Xc_InitCurrentPosition;
  
  xc_storage_cpos.crc16 = crc16((uint8_t *)&xc_storage_cpos.cpos, sizeof(Xc_CurrentPosition));
  
  eEPRom_Write(XC_STORAGE_CPOS_ADDRESS, (const uint8_t*)&xc_storage_cpos, sizeof(Xc_StorageCPosType));
  
  Xc_CurrentPosition = Xc_InitCurrentPosition;
  
  printf("Xc Init current position saved!\r\n");
}

static void storage_save_inituplt(void)
{
  memset(&xc_storage_uplt, 0, sizeof(Xc_StorageUpltType));
  
  xc_storage_uplt.uplt = Xc_InitUpLimit;
  
  xc_storage_uplt.crc16 = crc16((uint8_t *)&xc_storage_uplt.uplt, sizeof(Xc_UpLimit));
  
  eEPRom_Write(XC_STORAGE_UPLT_ADDRESS, (const uint8_t*)&xc_storage_uplt, sizeof(Xc_StorageUpltType));
  
  Xc_UpLimit = Xc_InitUpLimit;
  
  printf("Xc Init up limit saved!\r\n");
}

void Storage_xx_save(uint8_t type)
{
  if(type == 1)
  {
    memset(&xc_storage_ottm, 0, sizeof(Xc_StorageOttmType));
    
    xc_storage_ottm.ottm = Xc_OutTime;
    
    xc_storage_ottm.crc16 = crc16((uint8_t *)&xc_storage_ottm.ottm, sizeof(Xc_OutTime));
    
    eEPRom_Write(XC_STORAGE_OTTM_ADDRESS, (const uint8_t*)&xc_storage_ottm, sizeof(Xc_StorageOttmType));
    
    printf("Xc out time save success.\r\n");
  }
  else if(type == 2)
  {
    memset(&xc_storage_cpos, 0, sizeof(Xc_StorageCPosType));
    
    xc_storage_cpos.cpos = Xc_CurrentPosition;
    
    xc_storage_cpos.crc16 = crc16((uint8_t *)&xc_storage_cpos.cpos, sizeof(Xc_CurrentPosition));
    
    eEPRom_Write(XC_STORAGE_CPOS_ADDRESS, (const uint8_t*)&xc_storage_cpos, sizeof(Xc_StorageCPosType));
    
    printf("Xc current position save success.\r\n");
  }
  else if(type == 3)
  {
    memset(&xc_storage_uplt, 0, sizeof(Xc_StorageUpltType));
    
    xc_storage_uplt.uplt = Xc_UpLimit;
    
    xc_storage_uplt.crc16 = crc16((uint8_t *)&xc_storage_uplt.uplt, sizeof(Xc_UpLimit));
    
    eEPRom_Write(XC_STORAGE_UPLT_ADDRESS, (const uint8_t*)&xc_storage_uplt, sizeof(Xc_StorageUpltType));
    
    printf("Xc up limit save success.\r\n");
  }
}

uint8_t Storage_xx_load(void)
{
  uint16_t crc;
  
/***** out time */
  memset(&xc_storage_ottm, 0, sizeof(Xc_StorageOttmType));
  
  eEPRom_Read(XC_STORAGE_OTTM_ADDRESS, (uint8_t*)&xc_storage_ottm, sizeof(Xc_StorageOttmType));
  
  crc = crc16((uint8_t *)&xc_storage_ottm.ottm, sizeof(Xc_OutTime));
  
  if(xc_storage_ottm.crc16 != crc)
  {
    printf("ottm crc check error:0x%04X, 0x%04X\r\n", xc_storage_ottm.crc16, crc);
    storage_save_initottm();
    return 1;
  }
  
  if(Xc_CheckOutTime(xc_storage_ottm.ottm) != 0)
  {
    storage_save_initottm();
    return 2;
  }
  
  Xc_OutTime = xc_storage_ottm.ottm;
  
  
/***** current position */
  memset(&xc_storage_cpos, 0, sizeof(Xc_StorageCPosType));
  
  eEPRom_Read(XC_STORAGE_CPOS_ADDRESS, (uint8_t*)&xc_storage_cpos, sizeof(Xc_StorageCPosType));
  
  crc = crc16((uint8_t *)&xc_storage_cpos.cpos, sizeof(Xc_CurrentPosition));
  
  if(xc_storage_cpos.crc16 != crc)
  {
    printf("cpos crc check error:0x%04X, 0x%04X\r\n", xc_storage_cpos.crc16, crc);
    storage_save_initcpos();
    return 3;
  }
  
  if(Xc_CheckCurrentPosition(xc_storage_cpos.cpos) != 0)
  {
    storage_save_initcpos();
    return 4;
  }
  
  Xc_CurrentPosition = xc_storage_cpos.cpos;
  
  
/***** up limit */
  memset(&xc_storage_uplt, 0, sizeof(Xc_StorageUpltType));
  
  eEPRom_Read(XC_STORAGE_UPLT_ADDRESS, (uint8_t*)&xc_storage_uplt, sizeof(Xc_StorageUpltType));
  
  crc = crc16((uint8_t *)&xc_storage_uplt.uplt, sizeof(Xc_UpLimit));
  
  if(xc_storage_uplt.crc16 != crc)
  {
    printf("uplt crc check error:0x%04X, 0x%04X\r\n", xc_storage_uplt.crc16, crc);
    storage_save_inituplt();
    return 5;
  }
  
  if(Xc_CheckUpLimit(xc_storage_uplt.uplt) != 0)
  {
    storage_save_inituplt();
    return 6;
  }
  
  Xc_UpLimit = xc_storage_uplt.uplt;
  
  printf("up_limit:%d\r\n", Xc_UpLimit);
  printf("out_time:%d\r\n", Xc_OutTime);
  printf("curt_pos:%d\r\n", Xc_CurrentPosition);
  
  return 0;
}
